
#include "BSP_Sleep.h"
#include "log/log2.h"

#include "FreeRTOS.h"
#include "task.h"

#include <phNfcLib_Initialization.h>
#include "Utility.h"
#include <Reader/Reader.h>
// #include <Reader/ReaderDesfire2.h>
#include "reader_mfdf.h"
#include "reader_samav3.h"
#include "reader_key_store.h"
#include <Reader/apple_epc.h>
#include "phDriver.h"
#include "config/config3.h"

/*=============================================================*/
/*
get_uid_app_key : 50801750E819E5D2B2BD772E90D8AFF3
get_uid_app_key_id: 00
get_uid_app_id : F568A0
get_uid_file_id : 00
File_size : 7 bytes

User_id_app_key: 39949D07A573E66920A082BABB58C179
User_id_app_key_id : 00
User_id_app_id : F569A0
User_id_file_id : 00
File_size : 5 bytes


Desfire Settings
card_master_key
app_master_key
diversification_key
file_read_key
app_id
file_id
file_size
Card Master Key: 50801750E819E5D2B2BD772E90D8AFF3
Application Master Key: 39949D07A573E66920A082BABB58C179
Diversification (NXP AN10922, slightly modified, please check provided cmac_test.py):
E795EB10BFAAD62994547938FB0CE46E77098167
File Read Key: 48C9DEC5BD43F1C03D2AC37B09842951
Application ID: F567A0
UID is open, anyone can read it.
File ID to Read: 0
File Size: 5 bytes
*/


#if 0
//获取分散因子
static int reader_read_switflane_uid(uint8_t* uid, uint8_t* ulen){
		int ret;
	//2. SELECT the Privacy application and authenticate using the undiversified key.

		uint8_t aid[3] = {0xF5,0x69,0xA0};
		ret = Reader_MFDF_SelectApplication(PHAL_MFDFEVX_SELECT_PRIMARY_APP, (uint8_t*)aid, NULL);
		if(ret){
			LOG2_ERR("select app(%02X%02X%02X) fail: %04X", aid[0],aid[1],aid[2], ret);
			return 1;
		}

	//3. Read the static UID/CSN of the credential following Privacy app authentication.
		uint8_t keyNo = 1;		
		uint8_t ver = 0;
		void* key_store = phNfcLib_GetDataParams(PH_COMP_KEYSTORE);
		//E795EB10BFAAD62994547938FB0CE46E77098167
		// uint8_t key_div[] = { 0xE7,0x95,0xEB,0x10,0xBF,0xAA, 0xD6,0x29,0x94,0x57,0x93,0x8F,0xB0,0xCE,0x46,0xE7,0x70,0x98,0x16 };

		// uint8_t master_key[16] = { 0x50,0x80,0x17,0x50,0xE8,0x19,0xE5,0xD2,0xB2,0xBD,0x77,0x2E,0x90,0xD8,0xAF,0xF3 };

		//get_uid_app_key : 39949D07A573E66920A082BABB58C179
		uint8_t app_key[16] = { 0x39,0x94,0x9D,0x07,0xA5,0x73,0xE6,0x69,0x20,0xA0,0x82,0xBA,0xBB,0x58,0xC1,0x79 };
		//uint8_t app_key[16] = { 0x39, 0x94, 0x9D, 0x07, 0xA5, 0x73, 0xE6, 0x69, 0x20, 0xA0, 0x82, 0xBA, 0xBB, 0x58, 0xC1, 0x79 };		
		uint8_t key_type = PH_KEYSTORE_KEY_TYPE_AES128;
		uint8_t key_no_card = 0;
		uint8_t* key = app_key;
		phKeyStore_FormatKeyEntry(key_store, keyNo, key_type);
		// phKeyStore_SetKeyAtPos(key_store, keyNo, 0, key_type, master_key, ver);
		phKeyStore_SetKeyAtPos(key_store, keyNo, 0, key_type, key, ver);
		ret = Reader_MFDF_AuthenticateAES(PHAL_MFDFEVX_NO_DIVERSIFICATION, keyNo, ver, key_no_card, NULL, 0);
		if(ret){
			LOG2_ERR("auth fail: %04X", ret);
			return 2;
		}


	uint8_t bFileNo = 0;
	uint8_t olen = 5;
	uint8_t *data = NULL;
	uint16_t rlen = 0;
	uint8_t offset[3] = {0x00, 0x00, 0x00};
	uint8_t length[3] = {olen, 0x00, 0x00};
	ret = Reader_MFDF_ReadData(PHAL_MFDFEVX_COMMUNICATION_ENC, PHAL_MFDFEVX_APPLICATION_CHAINING, bFileNo, offset, length, &data, &rlen);
	if(ret){
		LOG2_ERR("Reader_MFDF_ReadData fail: %04X", ret);
		return 6;
	}
	LOG2_BUF_DBG("data:", data, rlen);		
	memcpy(uid, data, rlen);
	*ulen = rlen;	
	uint8_t end_apdu[] = {0x90, 0xee, 0x00, 0x00, 0x00};
	uint8_t *end_rapdu;
	uint16_t end_rlen;
	phpalI14443p4_Sw_DataParams_t*	ppalI14443p4 = (phpalI14443p4_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_ISO14443P4);

	phpalI14443p4_Exchange(ppalI14443p4, PH_EXCHANGE_DEFAULT, end_apdu, sizeof(end_apdu), &end_rapdu, &end_rlen);
//7. DESELECT credential.
	phpalI14443p4_Deselect(ppalI14443p4);
	
	return 0;
}
#endif
static int reader_read_switflane_awc(const param_swiftlane_t* param, uint8_t* uid, uint8_t* ulen){
	int ret;
	const key_set_t* key_set = &param->awc_key_set;
	uint8_t evid = reader_mfdf_get_evid(key_set->key_id);
	if(evid == PHAL_MFDFEVX_SAMAV3_NONX_ID){
		//激活SAM AV3
		ret = samav3_activate2();
		if(ret){
			return 1;
		}
	}

	//2. SELECT the Privacy application and authenticate using the undiversified key.

	// uint8_t aid[3] = {0xF5,0x69,0xA0};
	uint8_t *aid = (uint8_t*)param->awc_key_set.aid;
	// ret = Reader_MFDF_SelectApplication(PHAL_MFDFEVX_SELECT_PRIMARY_APP, aid, NULL);
	ret = reader_mfdf_select_application(evid, PHAL_MFDFEVX_SELECT_PRIMARY_APP, aid, NULL);
	if(ret){
		LOG2_ERR("select app(%02X%02X%02X) fail: %04X", aid[0],aid[1],aid[2], ret);
		return 1;
	}

	//3. Read the static UID/CSN of the credential following Privacy app authentication.
	uint8_t ver = 0;
	uint8_t keyNo = 1;
	if(reader_ks_setup(param->awc_key_set.key_id, &keyNo, &ver)){
		LOG2_ERR("reader_ks_setup fail");
		return 2;
	}
	ret = reader_mfdf_authenticate_aes(evid, PHAL_MFDFEVX_NO_DIVERSIFICATION, keyNo, ver, key_set->key_no, NULL, 0);
	if(ret){
		LOG2_ERR("auth fail: %04X", ret);
		return 2;
	}

	uint8_t bFileNo = param->awc_file_no;
	uint8_t olen = param->awc_length;
	uint8_t *data = NULL;
	uint16_t rlen = 0;
	uint8_t offset[3] = {0x00, 0x00, 0x00};
	uint8_t length[3] = {olen, 0x00, 0x00};
	//ret = Reader_MFDF_ReadData(PHAL_MFDFEVX_COMMUNICATION_ENC, PHAL_MFDFEVX_APPLICATION_CHAINING, bFileNo, offset, length, &data, &rlen);
	ret = reader_mfdf_read_data(evid, PHAL_MFDFEVX_COMMUNICATION_ENC, PHAL_MFDFEVX_APPLICATION_CHAINING, bFileNo, offset, length, &data, &rlen);
	if(ret){
		LOG2_ERR("Reader_MFDF_ReadData fail: %04X", ret);
		return 6;
	}
	LOG2_BUF_DBG("data:", data, rlen);		
	memcpy(uid, data, rlen);
	*ulen = rlen;	
	uint8_t end_apdu[] = {0x90, 0xee, 0x00, 0x00, 0x00};
	uint8_t *end_rapdu;
	uint16_t end_rlen;
	phpalI14443p4_Sw_DataParams_t*	ppalI14443p4 = (phpalI14443p4_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_ISO14443P4);

	phpalI14443p4_Exchange(ppalI14443p4, PH_EXCHANGE_DEFAULT, end_apdu, sizeof(end_apdu), &end_rapdu, &end_rlen);
//7. DESELECT credential.
	phpalI14443p4_Deselect(ppalI14443p4);
	
	return 0;
}

/*=============================================================*/

/**
 * @brief 读取SWIFTLANE苹果钱包卡片数据
 * @param read Reader_T结构体指针
 * @param cred credential_t结构体指针，用于存储读取到的凭证数据
 * @return int 返回0表示成功，其他值表示错误代码
 */
int reader_read_switflane(Reader_T* read, credential_t* cred){
	int ret;
	cred->clen = 0;
	ret = reader_read_switflane_awc(&config_param.swiftlane, cred->credential, &cred->clen);
	if(ret){
		LOG2_ERR("reader_zk_read_uid fail: %d", ret);
		return ret;
	}
	cred->nbit = cred->clen * 8;
	cred->tag.type = HFTAG_SWIFTLANE;
	return 0;
}

static int reader_switflane_load_default_keys(void){
	int ret;
	//是否支持se
	if(!samav3_is_ready() || !reader_se_support()){
		LOG2_PRINT("SAM AV3 not found!");
		return -1;
	}

	//装载Apple DES密钥
	LOG2_PRINT("\nApple AES key loading: ");
	ret = samav3_load_default_key(SAM_KID_SW_AWC_APP, cfg_key_default.swiftlane_awc_app.data, 1, SAM_KEY_CLASS_PICC, SAM_KEY_T_AES_128, 1);
	if(ret < 0) {
		LOG2_PRINT("Failed to load Apple DES key: %d\n", ret);
	}
	else {
		LOG2_PRINT("Load Apple AES key successful!");
	}
	//装载Google AES密钥
	LOG2_PRINT("\n Google AES key loading: ");
	ret = samav3_load_default_key(SAM_KID_SW_SDC_READ, cfg_key_default.swiftlane_sdc_read.data, 1, SAM_KEY_CLASS_PICC, SAM_KEY_T_AES_128, 1);
	if(ret < 0) {
		LOG2_PRINT("Failed to load Google AES key: %d\n", ret);
	}
	else {
		LOG2_PRINT("Load Google AES key successful!");
	}

	return ret;
}


//初始化switflane
int reader_init_switflane(void){
	return reader_switflane_load_default_keys();
}
